package top.boycharse.blog.secruity.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import top.boycharse.blog.bean.Response.BaseResponse;
import top.boycharse.blog.common.Constants;
import top.boycharse.blog.secruity.SecruityConstant;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class JwtAuthenticateFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        Authentication authentication = null;
        try(InputStream inputStream = request.getInputStream()) {
            ObjectMapper mapper = new ObjectMapper();
            Map<String,String> map = mapper.readValue(inputStream,Map.class);
            String username = map.get("username");
            String password = map.get("password");
            authentication = this.getAuthenticationManager()
                    .authenticate(new UsernamePasswordAuthenticationToken(username,password));
        }catch (IOException e) {
            e.printStackTrace();
            authentication = this.getAuthenticationManager()
                    .authenticate(new UsernamePasswordAuthenticationToken("",""));
        }

        return authentication;
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            FilterChain chain, Authentication authResult) throws IOException, ServletException {
        User user = (User) authResult.getPrincipal();
        List<String> roles = user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());

        Key key = Keys.hmacShaKeyFor(SecruityConstant.SECRUITY_STRKEY.getBytes());

        String token = Jwts.builder()
                .setHeaderParam("TYP","JWT")
                .setSubject(user.getUsername())
                .setIssuer("www.boycharse.top")
                .claim("role",roles)
                .signWith(key)
                .compact();

        response.setHeader(SecruityConstant.SECRUITY_TOKEN,SecruityConstant.SECRUITY_TOKEN_PRE + token);
        response.setContentType(Constants.CONTENT_TYPE);

        // 返回json数据
        ObjectMapper mapper = new ObjectMapper();
        OutputStream outputStream = response.getOutputStream();
        mapper.writeValue(outputStream, BaseResponse.buildSuccessLogin());
        outputStream.flush();
        outputStream.close();
    }
}
